package com.fulin.sycnLife;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;

/**
 * 独占锁就是在同一时刻只能有一个线程获取到锁，而其他锁的线程只能处于同步队列中等待，只有获取到锁
 * 的线程释放了锁，后继的线程才能获取到锁
 * @author fulin16
 *
 */
public class Mutex {
	//静态内部类，自定义同步器
	private static class Sync extends AbstractQueuedSynchronizer{
		//是否处于占用状态
		protected boolean isHeldExclusively(){
			return getState() == 1;
		}
		//当状态为0的时候获取锁
		public boolean tryAcquire(int acquires){
			if(compareAndSetState(0,1)){
				setExclusiveOwnerThread(Thread.currentThread());
				return true;
			}
			return false;
		}
		//释放锁，将状态设置为0
		protected boolean tryRelease(int release){
			if(getState() == 0){
				throw new IllegalMonitorStateException();
			}
			setExclusiveOwnerThread(null);
			setState(0);
			return true;
		}
		//返回一个Condition,每个condition都包含一个condition队列
		Condition newCondition(){
			return new ConditionObject();
		}
	}
	
	//将需要的操作代理到Sync上即可
	private final Sync sync = new Sync();
	public void lock(){
		sync.acquire(1);
	}
	public boolean tryLock(){
		return sync.tryAcquire(1);
	}
	public void unlock(){
		sync.release(1);
	}
	public Condition newCondition(){
		return sync.newCondition();
	}
	public boolean isLocked(){
		return sync.isHeldExclusively();
	}
	public boolean hasQueuedThreads(){
		return sync.hasQueuedThreads();
	}
	public void lockInterruptibly() throws InterruptedException {
		sync.acquireInterruptibly(1);
	}
	public boolean tryLock(long timeout,TimeUnit unit) throws InterruptedException{
		return sync.tryAcquireNanos(1, unit.toNanos(timeout));
	}
}
